package dao;

import com.mongodb.*;
import org.bson.types.ObjectId;
import vo.BasePO;
import vo.Page;
import vo.User;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

/**
 * Created by Lykos on 15/11/13.
 */
public class MongoClient {

    public static void save(BasePO basePO) throws Exception {
        String tableName = basePO.getClass().getSimpleName();
        BasicDBObject basicDBObject = new BasicDBObject();
        basicDBObject.putAll(basePO.toMap());
        getDBCollection(tableName).insert(basicDBObject);
    }

    public static List find(Class classObject, Map map) throws Exception{
        String tableName = classObject.getSimpleName();
        DBCollection dbCollection = getDBCollection(tableName);
        BasicDBObject basicDBObject = new BasicDBObject();
        basicDBObject.putAll(map);
        DBCursor dbCursor = dbCollection.find(basicDBObject);
        List<BasePO> mapList = new ArrayList<>();
        while (dbCursor.hasNext()){
            DBObject object = dbCursor.next();
            BasePO basePO = (BasePO)classObject.newInstance();
            basePO.fromMap(object.toMap());
            mapList.add(basePO);
        }
        return mapList;
    }

    public static BasePO findBy_id(Class classObject,String _id) throws Exception{
        String tableName = classObject.getSimpleName();
        DBCollection dbCollection = getDBCollection(tableName);
        BasicDBObject where = new BasicDBObject();
        ObjectId objectId = new ObjectId(_id);
        where.put("_id",objectId);
        DBCursor dbCursor = dbCollection.find(where);
        if (dbCursor.hasNext()){
            DBObject object = dbCursor.next();
            BasePO basePO = (BasePO)classObject.newInstance();
            basePO.fromMap(object.toMap());
            return basePO;
        }
        return null;
    }


    public static void delBy_id(Class classObject,String _id) throws Exception{
        String tableName = classObject.getSimpleName();
        DBCollection dbCollection = getDBCollection(tableName);
        BasicDBObject where = new BasicDBObject();
        ObjectId objectId = new ObjectId(_id);
        where.put("_id",objectId);
        dbCollection.remove(where);
    }

    public static List find(BasePO searchPO) throws Exception{
        String tableName = searchPO.getClass().getSimpleName();
        DBCollection dbCollection = getDBCollection(tableName);
        BasicDBObject basicDBObject = new BasicDBObject();
        basicDBObject.putAll(searchPO.toMap());
        DBObject orderBy = new BasicDBObject();
        orderBy.put("createTime",-1);
        DBCursor dbCursor = dbCollection.find(basicDBObject).sort(orderBy);
        List<BasePO> mapList = new ArrayList<>();
        while (dbCursor.hasNext()){
            DBObject object = dbCursor.next();
            BasePO basePO = (BasePO)searchPO.getClass().newInstance();
            basePO.fromMap(object.toMap());
            mapList.add(basePO);
        }
        return mapList;
    }

    public static List findOrderBy(BasePO searchPO,Map orderByMay) throws Exception{
        String tableName = searchPO.getClass().getSimpleName();
        DBCollection dbCollection = getDBCollection(tableName);
        BasicDBObject basicDBObject = new BasicDBObject();
        basicDBObject.putAll(searchPO.toMap());
        Iterator<String> keys = orderByMay.keySet().iterator();
        DBObject orderBy = new BasicDBObject();
        while (keys.hasNext()){
            String key = keys.next();
            String desc = orderByMay.get(key).toString();
            if(desc.equals("desc")){
                orderBy.put(key,-1);
            }else{
                orderBy.put(key,1);
            }
        }
        DBCursor dbCursor = dbCollection.find(basicDBObject).sort(orderBy);
        List<BasePO> mapList = new ArrayList<>();
        while (dbCursor.hasNext()){
            DBObject object = dbCursor.next();
            BasePO basePO = (BasePO)searchPO.getClass().newInstance();
            basePO.fromMap(object.toMap());
            mapList.add(basePO);
        }
        return mapList;
    }


    public static void update(BasePO searchPO,String _id) throws Exception{
        System.out.println(_id+"0000000000000000000000000000000000");
        String tableName = searchPO.getClass().getSimpleName();
        DBCollection dbCollection = getDBCollection(tableName);
        BasicDBObject basicDBObject = new BasicDBObject();
        Map updateMap = searchPO.toMap();
        updateMap.remove("_id");
        basicDBObject.putAll(updateMap);
        BasicDBObject where = new BasicDBObject();
        ObjectId objectId = new ObjectId(_id);
        where.put("_id",objectId);
        dbCollection.update(where,basicDBObject,false,false);
        //dbCollection.setWriteConcern(WriteConcern.REPLICAS_SAFE);
        //dbCollection = null;
        //MongoFactory.destoryInstance();
    }


    public static Page findByPage(Page page,BasePO searchPO) throws Exception{
        String tableName = searchPO.getClass().getSimpleName();
        DBCollection dbCollection = getDBCollection(tableName);
        BasicDBObject basicDBObject = new BasicDBObject();
        basicDBObject.putAll(searchPO.toMap());
        DBObject orderBy = new BasicDBObject();
        orderBy.put("createTime",-1);
        DBCursor dbCursor = dbCollection.find(basicDBObject);
        if(dbCursor.hasNext()){
            page.setTotalSize(dbCursor.size());
            dbCursor = dbCollection.find(basicDBObject).sort(orderBy).skip(page.getCurrentPage()-1).limit(page.getPageSize());
            List<BasePO> mapList = new ArrayList<>();
            //			conllection.setWriteConcern(WriteConcern.REPLICAS_SAFE);
            while (dbCursor.hasNext()){
                DBObject object = dbCursor.next();
                BasePO basePO = (BasePO)searchPO.getClass().newInstance();
                basePO.fromMap(object.toMap());
                mapList.add(basePO);
            }
            page.setResults(mapList);
        }

        return page;
    }


    private static DBCollection getDBCollection(String tableName) throws Exception {
        DB db = MongoFactory.getInstance().getDB("controlTower");
        return db.getCollection(tableName);
    }


    public static void main(String[] args) throws Exception {
        User user = new User();
        user.setPassword("123");
        //user.set_id("5645a78ccc1782486dc570b3");
        update(user,"5645a78ccc1782486dc570b3");
//        DBCollection dbCollection = getDBCollection("User");
//        BasicDBObject basicDBObject = new BasicDBObject();
//        ObjectId objectId = new ObjectId("5645a78ccc1782486dc570b3");
//        basicDBObject.put("_id",objectId);
//        DBCursor dbCursor = dbCollection.find(basicDBObject);
//        System.out.println(dbCursor.size());
    }
}
